package com.ajhlp.app.phoneDetailQuery.service;

import java.util.List;

import javax.annotation.Resource;


import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.stereotype.Service;

import com.ajhlp.app.phoneDetailQuery.model.PhoneNumRule;
import com.ajhlp.app.phoneDetailQuery.model.PhoneNumRuleJsonMeta;
import com.ajhlp.app.phoneDetailQuery.rule.Rule;
import com.ajhlp.app.phoneDetailQuery.rule.RuleItem;
import com.ajhlp.app.phoneDetailQuery.rule.RuleItemType;
import com.ajhlp.app.phoneDetailQuery.rule.RuleQueryCondition;

@Service
public class PhoneNumMatchRuleService {
	private Logger log = Logger.getLogger(getClass());
	
	@Resource
	private IPhoneRuleService ruleService;


	public IPhoneRuleService getRuleService() {
		return ruleService;
	}

	public void setRuleService(IPhoneRuleService ruleService) {
		this.ruleService = ruleService;
	}

	public Rule match(String phoneNum){
		
		if(phoneNum == null || phoneNum.equals("")){
			return null;
		}
		
		RuleQueryCondition condition = new RuleQueryCondition();
		condition.setOrder("desc");
		condition.setOrderColumn("price");
		
		List<Rule> rules = ruleService.searchRule(condition);
		
		for(int i=0;i<rules.size();i++){
			
			if(match(phoneNum, rules.get(i))){
				return rules.get(i);
			}
		}
		
		return null;
	}
	
	public boolean match(String phoneNum, Rule rule){
		char[] nums = phoneNum.toCharArray();
		
		RuleItem[] items = rule.getItems();
		
		if(items == null){
			items = JsonUtil.converJsonToObj(rule.getRegulation(), RuleItem[].class);
			rule.setItems(items);
		}
		
		if(nums.length != items.length){
			return false;
		}
		
		for(int i=0;i<nums.length;i++){
			
			RuleItem item = items[i];
			
			if(isStaticNumberType(item)){
				
				if(nums[i] == getTargetCharByRuleItemType(item.getType())){
					continue;
				}else{
					return false;
				}
			}else if(item.getType().equals(RuleItemType.ANY)){
				continue;
			}else if(item.getType().equals(RuleItemType.SAME)){
				
				if(nums[i] == nums[item.getSameItemIndex()]){
					continue;
				}else{
					return false;
				}
				
			}else if(item.getType().equals(RuleItemType.ADD)){
				
				if(nums[i] - nums[i-1] == 1){
					continue;
				}else{
					return false;
				}
			}else if(item.getType().equals(RuleItemType.SUB)){
				
				if(nums[i] - nums[i-1] == -1){
					continue;
				}else{
					return false;
				}
			}
			
		}
		
		return true;
	}
	
	/**
	 * 是否为常数
	 * @param detail
	 * @return
	 */
	public boolean isStaticNumberType(RuleItem item){
		
		if(item.getType().equals(RuleItemType.ZERO) ||
				item.getType().equals(RuleItemType.ONE) ||
				item.getType().equals(RuleItemType.TWO) ||
				item.getType().equals(RuleItemType.THREE) ||
				item.getType().equals(RuleItemType.FOUR) ||
				item.getType().equals(RuleItemType.FIVE) ||
				item.getType().equals(RuleItemType.SIX) ||
				item.getType().equals(RuleItemType.SEVEN) ||
				item.getType().equals(RuleItemType.EIGHT) ||
				item.getType().equals(RuleItemType.NINE)){
			return true;
		}
		
		return false;
	}
	
	public char getTargetCharByRuleItemType(RuleItemType type){
		if(type.equals(RuleItemType.ZERO)){
			return '0';
		}else if(type.equals(RuleItemType.ONE)){
			return '1';
		}else if(type.equals(RuleItemType.TWO)){
			return '2';
		}else if(type.equals(RuleItemType.THREE)){
			return '3';
		}else if(type.equals(RuleItemType.FOUR)){
			return '4';
		}else if(type.equals(RuleItemType.FIVE)){
			return '5';
		}else if(type.equals(RuleItemType.SIX)){
			return '6';
		}else if(type.equals(RuleItemType.SEVEN)){
			return '7';
		}else if(type.equals(RuleItemType.EIGHT)){
			return '8';
		}else {
			return '9';
		}
	}
	
	public PhoneNumRuleJsonMeta getJsonMeta(PhoneNumRule rule){
		ObjectMapper objectMapper = new ObjectMapper();
		try {
			return objectMapper.readValue(rule.getJsonMeta(), PhoneNumRuleJsonMeta.class);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			log.error("获取号码规则json描述信息失败", e);
			return null;
		}
	}
	
}
